package com.tencent.wxcloudrun.service.business.fangdong;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tencent.wxcloudrun.config.CustomException;
import com.tencent.wxcloudrun.dao.XApplyLandMapper;
import com.tencent.wxcloudrun.pojo.bo.MediaInfo;
import com.tencent.wxcloudrun.pojo.bo.NoticeConstant;
import com.tencent.wxcloudrun.pojo.dto.req.DealApplyReq;
import com.tencent.wxcloudrun.pojo.dto.resp.GetApplyAuthHouseListResp;
import com.tencent.wxcloudrun.pojo.dto.resp.GetApplyAuthListResp;
import com.tencent.wxcloudrun.pojo.dto.resp.ManageGetOneResp;
import com.tencent.wxcloudrun.pojo.dto.resp.ManagePageResp;
import com.tencent.wxcloudrun.pojo.po.*;
import com.tencent.wxcloudrun.service.*;
import com.tencent.wxcloudrun.service.business.NoticeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class ManageService {

    @Resource
    private XApplyLandMapper xApplyLandMapper;

    @Resource
    private XConstantService xConstantService;

    @Resource
    private XApplyLandService xApplyLandService;

    @Resource
    private XPersonInfoService xPersonInfoService;

    @Resource
    private XHouseInfoService xHouseInfoService;

    @Resource
    private NoticeService noticeService;

    @Resource
    private XHouseAuthMiddleService xHouseAuthMiddleService;

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    public String power(String key, String clientIp) {
        log.info(">>>>>> 开始判断是否有进入超管页面的权限。");

        // 如果提供了客户端IP，检查是否被锁定
        if (clientIp != null && !clientIp.trim().isEmpty()) {
            String lockKey = "admin_power_lock_" + clientIp;
            String lockValue = redisTemplate.opsForValue().get(lockKey);
            if (lockValue != null) {
                // 检查是否还在锁定期内
                long lockTime = Long.parseLong(lockValue);
                long currentTime = System.currentTimeMillis();
                long lockDuration = 15 * 60 * 1000; // 15分钟锁定时间

                if (currentTime - lockTime < lockDuration) {
                    long remainingTime = (lockDuration - (currentTime - lockTime)) / 1000 / 60; // 剩余分钟数
                    throw new CustomException("多次验证失败，请再等待" + remainingTime + "分钟后再次输入");
                } else {
                    // 锁定时间已过，清除锁定记录
                    redisTemplate.delete(lockKey);
                    redisTemplate.delete("admin_power_fail_count_" + clientIp);
                }
            }
        }

        LambdaQueryWrapper<XConstant> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(XConstant::getType01, "applyLand")
                .eq(XConstant::getOpenFlag, "open")
                .last("LIMIT 1");
        XConstant applyLand = xConstantService.getOne(queryWrapper);
        if (applyLand == null) {
            return "no";
        }

        boolean isValid = key.equals(applyLand.getValue01());

        // 如果提供了客户端IP，处理失败次数记录
        if (clientIp != null && !clientIp.trim().isEmpty()) {
            if (isValid) {
                // 验证成功，清除失败记录
                redisTemplate.delete("admin_power_fail_count_" + clientIp);
                redisTemplate.delete("admin_power_lock_" + clientIp);
            } else {
                // 验证失败，增加失败次数
                String failCountKey = "admin_power_fail_count_" + clientIp;
                String failCountStr = redisTemplate.opsForValue().get(failCountKey);
                int failCount = failCountStr == null ? 0 : Integer.parseInt(failCountStr);
                failCount++;

                if (failCount >= 3) {
                    // 达到3次失败，设置锁定
                    String lockKey = "admin_power_lock_" + clientIp;
                    redisTemplate.opsForValue().set(lockKey, String.valueOf(System.currentTimeMillis()));
                    redisTemplate.delete(failCountKey);
                    throw new CustomException("多次验证失败，请再等待15分钟后再次输入");
                } else {
                    // 记录失败次数，设置过期时间为15分钟
                    redisTemplate.opsForValue().set(failCountKey, String.valueOf(failCount));
                    redisTemplate.expire(failCountKey, java.time.Duration.ofMinutes(15));
                }
            }
        }

        return isValid ? "yes" : "no";
    }


    public List<ManagePageResp> getManagePage(String key, String tel) {
        log.info(">>>>>> 开始处理审批。");
        String power = power(key, null);
        if ("no".equals(power)) {
            throw new CustomException("没有 审批处理的权限。");
        }
        List<ManagePageResp> managePageRespList = xApplyLandMapper.findManagePageByTel(tel);
        List<ManagePageResp> respList = new ArrayList<>();
        for (ManagePageResp managePageResp : managePageRespList) {
            ManagePageResp pageResp = new ManagePageResp();
            pageResp.setLandId(managePageResp.getLandId());
            pageResp.setTel(managePageResp.getTel());
            pageResp.setInfo("待审批");
            respList.add(pageResp);
        }
        return respList;
    }

    public ManageGetOneResp getOne(String key, String landId) {
        log.info(">>>>>> 获取审批详情页数据。");
        String power = power(key, null);
        if ("no".equals(power)) {
            throw new CustomException("没有 审批处理的权限。");
        }
        LambdaQueryWrapper<XApplyLand> xApplyLandLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xApplyLandLambdaQueryWrapper.eq(XApplyLand::getOpenId, landId);
        XApplyLand oneByOpenId = xApplyLandService.getOne(xApplyLandLambdaQueryWrapper);
        ManageGetOneResp manageGetOneResp = new ManageGetOneResp();
        manageGetOneResp.setLandId(oneByOpenId.getOpenId());
        if (StrUtil.isNotBlank(oneByOpenId.getHousePic())) {
            manageGetOneResp.setHousePic(JSON.parseArray(oneByOpenId.getHousePic(), MediaInfo.class));
        }
        if (StrUtil.isNotBlank(oneByOpenId.getLeasePic())) {
            manageGetOneResp.setLeasePic(JSON.parseArray(oneByOpenId.getLeasePic(), MediaInfo.class));
        }
        if (StrUtil.isNotBlank(oneByOpenId.getCardZheng())) {
            manageGetOneResp.setCardZheng(JSON.parseObject(oneByOpenId.getCardZheng(), MediaInfo.class));
        }
        if (StrUtil.isNotBlank(oneByOpenId.getCardFan())) {
            manageGetOneResp.setCardFan(JSON.parseObject(oneByOpenId.getCardFan(), MediaInfo.class));
        }
        if (StrUtil.isNotBlank(oneByOpenId.getSignPic())) {
            manageGetOneResp.setSignPic(JSON.parseObject(oneByOpenId.getSignPic(), MediaInfo.class));
        }
        manageGetOneResp.setTel(oneByOpenId.getTel());
        return manageGetOneResp;
    }

    @Transactional(rollbackFor = Exception.class)
    public String dealFailApply(String key, String landId, String errInfo) {
        log.info(">>>>>> 开始处理失败的审批情况。");
        String power = power(key, null);
        if ("no".equals(power)) {
            throw new CustomException("没有 审批处理的权限。");
        }
        XApplyLand xApplyLand = new XApplyLand();
        xApplyLand.setOpenId(landId);
        xApplyLand.setStatus("2");
        xApplyLand.setFailInfo(errInfo);
        xApplyLand.setUpdateTime(new Date());
        LambdaQueryWrapper<XApplyLand> xApplyLandLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xApplyLandLambdaQueryWrapper.eq(XApplyLand::getOpenId, landId);
        xApplyLandService.update(xApplyLand, xApplyLandLambdaQueryWrapper);
        noticeService.createNoticeByOpenid(landId, "land", String.format(NoticeConstant.LAND_APPROVE_TITLE, "失败"),
                String.format(NoticeConstant.LAND_APPROVE_CONTENT, "失败，原因是：" + errInfo + "，请于个人信息中进行修改后重新提交申请。"));
        return "success";
    }

    @Transactional(rollbackFor = Exception.class)
    public String dealSuccessApply(DealApplyReq req) {
        log.info(">>>>>> 开始处理成功的审批情况。  " + JSON.toJSONString(req));
        String power = power(req.getKey(), null);
        if ("no".equals(power)) {
            throw new CustomException("没有 审批处理的权限。");
        }
        Date date = new Date();
        LambdaQueryWrapper<XApplyLand> xApplyLandLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xApplyLandLambdaQueryWrapper.eq(XApplyLand::getOpenId, req.getLandId());
        XApplyLand oneByOpenId = xApplyLandService.getOne(xApplyLandLambdaQueryWrapper);
        if ("3".equals(oneByOpenId.getStatus())) {
            throw new CustomException("已正常的情况下不能发起成功审批！");
        }
        XPersonInfo xPersonInfo = new XPersonInfo();
        xPersonInfo.setPersonId(req.getLandId());
        xPersonInfo.setPersonType("landlord");
        xPersonInfo.setPhone(oneByOpenId.getTel());
        // 检查身份证号码，并获取生日信息
//        xPersonInfo.setBirthday(IdcardUtil.getBirthDate(req.getIdCard()));
        xPersonInfo.setSex(req.getSex());
        xPersonInfo.setCardName(req.getName());
        xPersonInfo.setCardId(req.getIdCard());
        xPersonInfo.setCardFront(oneByOpenId.getCardZheng());
        xPersonInfo.setCardBack(oneByOpenId.getCardFan());
        xPersonInfo.setHousePic(oneByOpenId.getHousePic());
        xPersonInfo.setLeasePic(oneByOpenId.getLeasePic());
        xPersonInfo.setSignPic(oneByOpenId.getSignPic());
        xPersonInfo.setCreateTime(date);
        xPersonInfo.setUpdateTime(date);
        xPersonInfoService.save(xPersonInfo);
        XApplyLand xApplyLand = new XApplyLand();
        xApplyLand.setId(oneByOpenId.getId());
        xApplyLand.setStatus("3");
        xApplyLand.setFailInfo("");
        xApplyLand.setUpdateTime(date);
        xApplyLandService.updateById(xApplyLand);
        log.info(">>>>>>尝试清空用户的角色缓存。");
        redisTemplate.delete("identity_" + req.getLandId());
        noticeService.createNoticeByOpenid(req.getLandId(), "land", String.format(NoticeConstant.LAND_APPROVE_TITLE, "通过"),
                String.format("恭喜" + NoticeConstant.LAND_APPROVE_CONTENT, "已通过，快去房屋管理模块中进行房屋新增吧！"));
        return "success";
    }

    public List<GetApplyAuthListResp> getApplyAuthList(String key) {
        String power = power(key, null);
        if ("no".equals(power)) {
            throw new CustomException("没有 审批处理的权限。");
        }
        List<XHouseAuthMiddle> list = xHouseAuthMiddleService.list();
        List<GetApplyAuthListResp> respList = new ArrayList<>();
        for (XHouseAuthMiddle authMiddle : list) {
            GetApplyAuthListResp resp = new GetApplyAuthListResp();
            List<String> stringList = JSON.parseArray(authMiddle.getHouseList(), String.class);
            resp.setName(authMiddle.getLandName() + "（" + stringList.size() + "）");
            resp.setApplyTime(DateUtil.format(authMiddle.getCreateTime(), "yyyy-MM-dd HH:mm:ss"));
            resp.setAuthId(authMiddle.getAuthId());
            respList.add(resp);
        }
        return respList;
    }

    @Transactional
    public String deleteApplyAuth(String key, String authId) {
        String power = power(key, null);
        if ("no".equals(power)) {
            throw new CustomException("没有 审批处理的权限。");
        }
        xHouseAuthMiddleService.removeById(authId);
        return "success";
    }

    public String getApplyAuthTel(String key, String authId) {
        String power = power(key, null);
        if ("no".equals(power)) {
            throw new CustomException("没有 审批处理的权限。");
        }
        LambdaQueryWrapper<XHouseAuthMiddle> xHouseAuthMiddleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xHouseAuthMiddleLambdaQueryWrapper.eq(XHouseAuthMiddle::getAuthId, authId);
        XHouseAuthMiddle xHouseAuthMiddle = xHouseAuthMiddleService.getOne(xHouseAuthMiddleLambdaQueryWrapper);
        return xHouseAuthMiddle.getApplyPhone();
    }

    public List<GetApplyAuthHouseListResp> getApplyAuthHouseList(String key, String authId) {
        String power = power(key, null);
        if ("no".equals(power)) {
            throw new CustomException("没有 审批处理的权限。");
        }
        LambdaQueryWrapper<XHouseAuthMiddle> xHouseAuthMiddleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xHouseAuthMiddleLambdaQueryWrapper.eq(XHouseAuthMiddle::getAuthId, authId);
        XHouseAuthMiddle xHouseAuthMiddle = xHouseAuthMiddleService.getOne(xHouseAuthMiddleLambdaQueryWrapper);
        List<String> stringList = JSON.parseArray(xHouseAuthMiddle.getHouseList(), String.class);
        LambdaQueryWrapper<XHouseInfo> xHouseInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xHouseInfoLambdaQueryWrapper.in(XHouseInfo::getHouseId, stringList);
        List<XHouseInfo> xHouseInfoList = xHouseInfoService.list(xHouseInfoLambdaQueryWrapper);
        List<GetApplyAuthHouseListResp> respList = new ArrayList<>();
        for (XHouseInfo houseInfo : xHouseInfoList) {
            GetApplyAuthHouseListResp houseListResp = new GetApplyAuthHouseListResp();
            houseListResp.setHouseId(houseInfo.getHouseId());
            houseListResp.setLeftInfo(houseInfo.getHouseName() + "_" + houseInfo.getFloor() + "_层" + houseInfo.getArea() + "平米");
            if ("yes".equals(houseInfo.getPicAuth())) {
                houseListResp.setAuthStatus("已认证");
            }
            if ("ing".equals(houseInfo.getPicAuth())) {
                houseListResp.setAuthStatus("认证中");
            }
            if (StrUtil.isBlank(houseInfo.getPicAuth()) || "no".equals(houseInfo.getPicAuth())) {
                houseListResp.setAuthStatus("未认证");
            }
            respList.add(houseListResp);
        }
        return respList;
    }

    @Transactional
    public String dealApplyAuth(String key, String houseId, String result) {
        String power = power(key, null);
        if ("no".equals(power)) {
            throw new CustomException("没有 审批处理的权限。");
        }
        LambdaQueryWrapper<XHouseInfo> xHouseInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xHouseInfoLambdaQueryWrapper.eq(XHouseInfo::getHouseId, houseId);
        XHouseInfo one = xHouseInfoService.getOne(xHouseInfoLambdaQueryWrapper);
        if ("no".equals(result) && "yes".equals(one.getPicAuth())) {
            throw new CustomException("认证过的房屋不能设为非认证");
        }
        XHouseInfo houseInfo = new XHouseInfo();
        houseInfo.setPicAuth(result);
        xHouseInfoService.update(houseInfo, xHouseInfoLambdaQueryWrapper);

        LambdaQueryWrapper<XHouseAuthMiddle> xHouseAuthMiddleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xHouseAuthMiddleLambdaQueryWrapper.like(XHouseAuthMiddle::getHouseList, houseId);
        XHouseAuthMiddle houseAuthMiddleServiceOne = xHouseAuthMiddleService.getOne(xHouseAuthMiddleLambdaQueryWrapper);
        String landlordId = one.getLandlordId();
        String houseName = one.getHouseName() != null ? one.getHouseName() : "房屋ID:" + houseId;

        if ("land".equals(houseAuthMiddleServiceOne.getApplyPersonType())) { // 如果发起人是房东，就只给房东发送认证结果通知
            if ("yes".equals(result)) {
                // 认证通过
                noticeService.createNoticeByOpenid(landlordId, "land",
                        String.format(NoticeConstant.HOUSE_AUTH_RESULT_TITLE, "通过"),
                        String.format(NoticeConstant.HOUSE_AUTH_APPROVE_CONTENT, houseName));
            } else {
                // 认证拒绝
                noticeService.createNoticeByOpenid(landlordId, "land",
                        String.format(NoticeConstant.HOUSE_AUTH_RESULT_TITLE, "未通过"),
                        String.format(NoticeConstant.HOUSE_AUTH_REJECT_CONTENT, houseName, result));
            }
        }
        if ("helpmate".equals(houseAuthMiddleServiceOne.getApplyPersonType())) { // 如果发起人是助理，要给房东与助理都发送通知信息
            // 获取助理的OpenId
            String helpmateId = houseAuthMiddleServiceOne.getCreateId();

            if ("yes".equals(result)) {
                // 认证通过 - 给房东发送通知
                noticeService.createNoticeByOpenid(landlordId, "land",
                        String.format(NoticeConstant.HOUSE_AUTH_RESULT_TITLE, "通过"),
                        String.format(NoticeConstant.HOUSE_AUTH_APPROVE_CONTENT, houseName));

                // 认证通过 - 给助理发送通知
                noticeService.createNoticeByOpenid(helpmateId, "helpmate",
                        String.format(NoticeConstant.HOUSE_AUTH_RESULT_TITLE, "通过"),
                        String.format(NoticeConstant.HOUSE_AUTH_APPROVE_CONTENT, houseName));
            } else {
                // 认证拒绝 - 给房东发送通知
                noticeService.createNoticeByOpenid(landlordId, "land",
                        String.format(NoticeConstant.HOUSE_AUTH_RESULT_TITLE, "未通过"),
                        String.format(NoticeConstant.HOUSE_AUTH_REJECT_CONTENT, houseName, result));

                // 认证拒绝 - 给助理发送通知
                noticeService.createNoticeByOpenid(helpmateId, "helpmate",
                        String.format(NoticeConstant.HOUSE_AUTH_RESULT_TITLE, "未通过"),
                        String.format(NoticeConstant.HOUSE_AUTH_REJECT_CONTENT, houseName, result));
            }
        }

        return "success";
    }

    /**
     * 缓存清理方法
     */
    public String clearCache(String key, String cacheKey) {
        log.info(">>>>>> 开始清理缓存，缓存键值: {}", cacheKey);
        String power = power(key, null);
        if ("no".equals(power)) {
            throw new CustomException("没有缓存清理的权限。");
        }

        try {
            // 删除指定的缓存键
            Boolean deleted = redisTemplate.delete(cacheKey);
            if (deleted) {
                log.info(">>>>>> 缓存清理成功，键值: {}", cacheKey);
                return "缓存清理成功";
            } else {
                log.warn(">>>>>> 缓存键不存在或已被删除，键值: {}", cacheKey);
                return "缓存键不存在或已被删除";
            }
        } catch (Exception e) {
            log.error(">>>>>> 缓存清理失败，键值: {}, 错误信息: {}", cacheKey, e.getMessage());
            throw new CustomException("缓存清理失败: " + e.getMessage());
        }
    }
}
